import {ethers} from "ethers";
import tp from 'tp-js-sdk';
import usdtAbi from "./usdt.json";
import walletException from "./wallet-exception.js";
import walletConfig from "./wallet-config";

const {ethereum} = window;

let wallet = {};

wallet.getProvider = () => {
    return new ethers.providers.Web3Provider(ethereum);
}

wallet.getSigner = () => {
    return wallet.getProvider().getSigner();
}

wallet.getContractSinger = (address, abi) => {
    let signer = wallet.getSigner();
    return new ethers.Contract(address, abi, signer);
}

//获取地址
wallet.getAddress = async () => {
    try {
        let isTpWallet = tp.isConnected();
        if (isTpWallet) {
            let currentWallt = await tp.getCurrentWallet();
            return currentWallt.data.address;
        } else {
            let accounts = await ethereum.request({
                method: 'eth_requestAccounts'
            });
            return accounts[0];
        }
    } catch (error) {
        console.log("getAddress error=>", error);
    }
    return '0x0000000000000000000000000000000000000000';
}

wallet.getContract = (address, abi) => {
    let provider = wallet.getProvider();
    return new ethers.Contract(address, abi, provider);
}

// 查询代币余额
wallet.getTokenBalance = async (token, owner) => {
    let tokenContract = wallet.getContract(token, usdtAbi)
    let res = await tokenContract.balanceOf(owner);
    return Number(ethers.utils.formatEther(res)).toFixed(2);
}

// 代币转账
wallet.transferTo = async (token, to, amount) => {
    try {
        const contract = wallet.getContractSinger(token, usdtAbi);
        let res = await contract.transfer(to, amount);
        return wallet.verifyHash(res);
    } catch (err) {
        return await walletException.handlerException(err);
    }
}

// 验证hash
wallet.verifyHash = (res) => {
    return new Promise(function (resolve, reject) {
        if (res && res.hash) {
            let task = setInterval(async function () {
                let receipt = await wallet.getProvider().getTransactionReceipt(res.hash);
                if (!receipt) {
                    return;
                }
                if (receipt.status === 0) {
                    reject(new Error("On-chain transaction failed"));
                } else {
                    resolve(res.hash)
                }
                clearInterval(task);
            }, 1000);
        } else {
            reject(new Error("On-chain transaction failed"));
        }
    });
}

wallet.checkChainId = async () => {
    let chainId = ethereum.net_version;
    console.log("chai", chainId);
    if (chainId !== 0x38) {
        await ethereum.request({
            method: "wallet_addEthereumChain",
            params: [
                {
                    "chainId": 0x38,
                    "chainName": "BSC Mainnet",
                    "rpcUrls": ["https://bsc-dataseed2.ninicoin.io"],
                    "blockExplorerUrls": ["https://bscscan.com/"],
                    "nativeCurrency": {
                        "name": "BNB",
                        "symbol": "BNB",
                        "decimals": 18
                    },
                }
            ]
        });
        await ethereum.request({
            "method": "wallet_switchEthereumChain",
            "params": [
                {
                    "chainId": 0x38
                }
            ]
        });
    }
}

wallet.mintCat = async (signature, data) => {
    try {
        const contract = wallet.getContractSinger(walletConfig.factoryAddress, walletConfig.factoryAbi);
        let res = await contract.mintCat(signature, data, {gasLimit: 500000});
        return wallet.verifyHash(res);
    } catch (err) {
        return await walletException.handlerException(err);
    }
}

wallet.extract = async (signature, data) => {
    try {
        const contract = wallet.getContractSinger(walletConfig.factoryAddress, walletConfig.factoryAbi);
        let res = await contract.extract(signature, data);
        return wallet.verifyHash(res);
    } catch (err) {
        return await walletException.handlerException(err);
    }
}

wallet.addLiquidity = async (signature, data) => {
    try {
        const contract = wallet.getContractSinger(walletConfig.factoryAddress, walletConfig.factoryAbi);
        let res = await contract.addLiquidity(signature, data, {gasLimit: 500000});
        return wallet.verifyHash(res);
    } catch (err) {
        return await walletException.handlerException(err);
    }
}

wallet.removeLiquidity = async (signature, data) => {
    try {
        const contract = wallet.getContractSinger(walletConfig.factoryAddress, walletConfig.factoryAbi);
        let res = await contract.removeLiquidity(signature, data, {gasLimit: 500000});
        return wallet.verifyHash(res);
    } catch (err) {
        return await walletException.handlerException(err);
    }
}

export default wallet;
